Copyright © 2020 Maxime Devos <maxime.devos@student.kuleuven.be>
This file is part of rehash.

rehash is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or (at
your option) any later version.

rehash is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with rehash.  If not, see <http://www.gnu.org/licenses/>.

* What is rehash?

rehash is a GNUnet service for mapping a hash of one type o
a corresponding hash of another via the DHT.  A program
can insert hash->hash mappings into the rehash service,
which then are stored locally and pushed onto the network.
Another program, possibly on another peer, could then look
up a hash by one type and find a hash of another.

TODO: implement content pushing

* How to use?

The following components are planned:

- a C implementation
- a Scheme binding to the C implementation
- a nice guile-fibers binding to the former
- a REST API
  (should be less problematic to include in Guix
  than depending on GNUnet)
- a web demo

* Limitations

Any hash->hash mappings found in this manner can of course
not be guaranteed to be correct (^), so don't forget to verify
the found mapping, and if it turns out to be incorrect,
don't forget to tell that to the rehash service, to prevent
further propagation of bad mappings.

TODO: implement this

(^) An evil peer could spam incorrect hash->hash mappings.

* Limitations to limitations

TODO locally delete old mappings if a good mapping becomes known.
TODO work out the mathematics on how effective an attacker could be
TODO work out countermeasures

I don't think evil peers will be a large-scale problem in practice
(what would be the point?), although targeted denial-of-service by
spamming attacks would be possible I guess.

* For what would this be useful?

This service was written for use in guix-gnunet, an experimental
fork of guix for integrating GNUnet in Guix. More specifically, for
finding substitutes over GNUnet (including sources, which usually are
fixed-output derivations).

In the case of sources (or more technically correct, any fixed-output
derivation), its nix (?) hash is known, but this hash isn't directly
useful for downloading the source over the GNUnet file-sharing system,
which has its own directory format and (presumably? (*)) splits
(large) files in some tree structure and hashes this tree recursively
(or something (*)). The rehash service allows for converting
between hash types (for some value of unreliable).

In case of variable-output derivations, some authorised substitute
server still needs to publish signed narinfos. The local Guix
could then try to ‘convert’ the nix (?) hash in the narinfo to an
appropriate GNUnet hash, and try to download the substitute over
GNUnet.

(*) TODO verify with the ECRS paper.

* A path not taken: embedding the GNUnet hash in the narinfo

This is what the wip-ipfs-substitutes patch does (*2). However,
GNUnet isn't quite stable yet (but it's getting better,
for some protocols informational RFCs are written / have been
written / have received feedback / etc.), so it seems unreasonable
for the upstream substitute servers to include GNUnet hashes
anytime soon.

If GNUnet (or at least its file-sharing protocols)  is stable enough,
this will probably be implemented, to avoid bad mappings.

(Note: generating GNUnet hashes doesn't quite require the full
stack, and could be done fully in Scheme without too much trouble.
See (*3) for a suspended work-in-progress.)

(*2) https://issues.guix.gnu.org/33899
(*3) https://notabug.org/mdevos/scheme-gnunet

* Another path not taken: embedding the GNUnet hash in the origin specification

Advantage: no incorrect hashes
Disadvantage: all origins would need to be updated, not very useful
for variable-output derivations (e.g. packages), whose inputs can change.

This may still be implemented if GNUnet becomes stable and popular enough,
but its applicability is limited.